From b0a4d66a6cf065ab0a4341ba88cc75dccfbe1141 Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Wed, 5 Apr 2006 17:41:51 +0100 Subject: [PATCH] Add new interface for allocating reserved event-channel ports to arbitrary Xen subsystems. Signed-off-by: Keir Fraser --- xen/common/event_channel.c | 52 +++++++++++++++++++++++++++++++++++++- xen/include/xen/event.h | 5 ++++ 2 files changed, 56 insertions(+), 1 deletion(-) diff --git a/xen/common/event_channel.c b/xen/common/event_channel.c index b37a6f183a..2f766f7d31 100644 --- a/xen/common/event_channel.c +++ b/xen/common/event_channel.c @@ -46,6 +46,7 @@ goto out; \ } while ( 0 ) + static int get_free_port(struct domain *d) { struct evtchn *chn; @@ -360,7 +361,7 @@ static long __evtchn_close(struct domain *d1, int port1) rc = -EINVAL; goto out; } - + port2 = chn1->u.interdomain.remote_port; BUG_ON(!port_is_valid(d2, port2)); @@ -438,6 +439,7 @@ long evtchn_send(unsigned int lport) return ret; } + void evtchn_set_pending(struct vcpu *v, int port) { struct domain *d = v->domain; @@ -471,6 +473,7 @@ void evtchn_set_pending(struct vcpu *v, int port) } } + void send_guest_virq(struct vcpu *v, int virq) { int port = v->virq_to_evtchn[virq]; @@ -479,6 +482,7 @@ void send_guest_virq(struct vcpu *v, int virq) evtchn_set_pending(v, port); } + void send_guest_pirq(struct domain *d, int pirq) { int port = d->pirq_to_evtchn[pirq]; @@ -486,6 +490,7 @@ void send_guest_pirq(struct domain *d, int pirq) evtchn_set_pending(d->vcpu[chn->notify_vcpu_id], port); } + static long evtchn_status(evtchn_status_t *status) { struct domain *d; @@ -550,6 +555,7 @@ static long evtchn_status(evtchn_status_t *status) return rc; } + long evtchn_bind_vcpu(unsigned int port, unsigned int vcpu_id) { struct domain *d = current->domain; @@ -585,6 +591,7 @@ long evtchn_bind_vcpu(unsigned int port, unsigned int vcpu_id) return rc; } + static long evtchn_unmask(evtchn_unmask_t *unmask) { struct domain *d = current->domain; @@ -620,6 +627,7 @@ static long evtchn_unmask(evtchn_unmask_t *unmask) return 0; } + long do_event_channel_op(GUEST_HANDLE(evtchn_op_t) uop) { long rc; @@ -694,6 +702,48 @@ long do_event_channel_op(GUEST_HANDLE(evtchn_op_t) uop) } +int evtchn_open_reserved_port(struct domain *d) +{ + struct evtchn *chn; + int port; + + spin_lock(&d->evtchn_lock); + + if ( (port = get_free_port(d)) >= 0 ) + { + chn = evtchn_from_port(d, port); + chn->state = ECS_RESERVED; + } + + spin_unlock(&d->evtchn_lock); + + return port; +} + + +void evtchn_close_reserved_port(struct domain *d, int port) +{ + struct evtchn *chn; + + spin_lock(&d->evtchn_lock); + + BUG_ON(!port_is_valid(d, port)); + + chn = evtchn_from_port(d, port); + chn->state = ECS_FREE; + chn->notify_vcpu_id = 0; + + spin_unlock(&d->evtchn_lock); +} + + +void evtchn_notify_reserved_port(struct domain *d, int port) +{ + struct evtchn *chn = evtchn_from_port(d, port); + evtchn_set_pending(d->vcpu[chn->notify_vcpu_id], port); +} + + int evtchn_init(struct domain *d) { spin_lock_init(&d->evtchn_lock); diff --git a/xen/include/xen/event.h b/xen/include/xen/event.h index 8487a25c7b..e56b991406 100644 --- a/xen/include/xen/event.h +++ b/xen/include/xen/event.h @@ -45,4 +45,9 @@ extern long evtchn_send(unsigned int lport); /* Bind a local event-channel port to the specified VCPU. */ extern long evtchn_bind_vcpu(unsigned int port, unsigned int vcpu_id); +/* Reserved event-channel ports for other Xen subsystems. */ +int evtchn_open_reserved_port(struct domain *d); +void evtchn_close_reserved_port(struct domain *d, int port); +void evtchn_notify_reserved_port(struct domain *d, int port); + #endif /* __XEN_EVENT_H__ */ -- 2.30.2